# Do not run data set on git/github until privacy has been cleared
################
##### Data
################
################
##### Research
################
################
##### Guess work
################
################
##### Notes:
################
### Source ----> Input ----> Model ----> Policy Estimates (output)
### (_so) (_in) (_mo) (_pe)
### values functions functions values
### & values & values
### arguments in functions should used "_var" and functions should "_f"
#invisible( list2env(call_params_f(),.GlobalEnv) )
# Each analytic code chunk will begin by listing all the inputs it needs, and
# the outputs it produces.
# - inputs: list
# - outputs: list
#### The key essential analytic steps are wrapted in a function
#chunk_name_of_chunk <- function(){
##########################################
##########################################
#
# here goes the essential analytic content
#
##########################################
##########################################
# return( ) # A list with all the objects
#} # generated inside the function
# The following line executes the code chunk and deposits its results
# into the current R enviornment:
#invisible( list2env(chunk_name_of_chunk(),.GlobalEnv) )
#
##### Execute values of the functions above when needed for the text:
# Anything under this comment is to create objects that are used in the body of
# text. Not to be used in the final results (could be deleted). Each of these
# object should end with the suffix _temp
# - inputs: none
# - outputs: all sources coming from data, research and guesswork
chunk_sources <- function(){
###############################################################################
###############################################################################
#############
##### Setup
#############
nsims_so <- 1e4
policy_estimate_so <- "Main Equation"
rescale_so <- TRUE
#############
##### Data
#############
# Create objects for data extracted from various sources
r_input1_so <- 0.1
r_input2_so <- 0.2
#############
##### Research
#############
# Create objects for parameters extracted from research papers
q_input1_so <- 0.5
q_input2_so <- 0.8
#############
##### Guess work
#############
# Create objects for variables from educated guesses or estimates
#############
##### Notes:
#############
# Notes for the objects defined above, including sources, explanations, etc.
k_input1_so <- 3
k_input2_so <- 4
#return( sapply( ls(pattern= "_so\\b"), function(x) get(x)) )
return (
list("nsims_so" = nsims_so,
"policy_estimate_so" = policy_estimate_so,
"rescale_so" = rescale_so,
"r_input1_so" = r_input1_so,
"r_input2_so" = r_input2_so,
"q_input1_so" = q_input1_so,
"q_input2_so" = q_input2_so,
"k_input1_so" = k_input1_so,
"k_input2_so" = k_input2_so
)
)
}
invisible(list2env(chunk_sources(),.GlobalEnv) )
Introduction
Summary of the issue and introduction to the policy analysis is conducted.
The goal of this analysis is to provide the best empirical information for policy makers debating the implementation of “mass deworming interventions” policy. This document describes all the analytical steps required to reproduce the analysis, and displaying the actual computer code use in each step. In addition to this report, the reader can find all the materials to reproduce the findings presented here in GitHub. The main output, presented in the results section of this report, can also be explored interactively for different assumptions on the corresponding shiny app.
Key policy estimates for policy makers
#my thoughts: should we forefront the conclusions before the methodology?
#Sandra: I think we should specify which approach we use to generate the graph, but keep the methodology before the conclusions.
???
Methodology
Explain what the final estimate indicator is, how the analysis is to be performed, what factors are looked at, etc.
The final estimate is the net present value of the deworming treatment, referred to as the Net Present Value (NPV). The report first describes the common elements across all three approaches, and then describe each approach in detail.
Common Structure
Introduce the starting point and the final policy estimate. Include alternative indicators of our final policy estimates as well.
The starting point is a comparison of a stream of benefits and costs over the lifetime of the recipients of deworming. The final policy estimate is the discounted sum of all costs and benefits, known as the Net Present Value (NPV). Benefits are equal to the additional lifetime earnings that individuals are expected to generate due to deworming treatment. These additional earnings are computed as a discounted sum over their working lifetime.
At a high level all three approaches focus on the same type of benefits: the increase in incomes over the lifetime of beneficiaries of deworming. This is likely an under-estimate of the benefits as it does not quantify the non-pecuniary effects of improved health. The costs can be separated into direct costs of implementing and evaluating deworming programs, and indirect costs, such as additional costs to the education system as a result of increased child attendance, associated with the benefits of deworming.
The main differences in benefits across the three approaches have to do with how to predict the earnings profiles over a lifecycle, and how to account for differences in worm prevalence rates and length of treatment across settings. Approaches 1 and 2 use different earning profiles, and approach 3 combines both earning profiles and adjusts for possible differences in prevalence rates of worm infections and length of treatment.
The main differences in costs between scenarios have to do with a) whether indirect costs are included, and b) how to compute the relevant unit cost for the analysis. The first two approaches include indirect costs and use the unit costs of a specific country (Kenya) where the study was originally conducted, while the third approach does not include indirect costs and use unit costs of various countries from data provided by Evidence Action.
Main Equation (the model)
Explanation for the main equation
Show all the details
\[\begin{equation}
y = r + q - k
\label{eq:1}
\tag{1}
\end{equation}\]
Where:
- \(y\): one-liner to define y
- \(r\): one-liner to define r
- \(k\): one-liner to define k
Alternative Equation
Explanation for the alternative equation
Show all the details
\[\begin{equation}
y = r + q + k
\label{eq:2}
\tag{2}
\end{equation}\]
Where:
- \(y\): one-liner to define y
- \(r\): one-liner to define r
- \(k\): one-liner to define k
# - inputs:
# - outputs:
chunk_test <- function(){
###############################################################################
###############################################################################
# random equation to use as our main equation to get the final result
mainequation_f <- function(r_final_var = 1,
q_final_var = 1,
k_final_var = 1) {
return (r_final_var + q_final_var - k_final_var)
}
# random equation to use as our alternative equation to get the final result
alternative_f <- function( r_final_var = 1,
q_final_var = 1,
k_final_var = 1){
return (r_final_var + q_final_var + k_final_var)
}
###############################################################################
###############################################################################
return(list("mainequation_f" = mainequation_f, "alternative_f" = alternative_f)) # Try to return only functions
}
invisible( list2env(chunk_test(),.GlobalEnv) )
##### Execute values of the functions above when needed for the text:
mainequation_in <- mainequation_f()
alternative_in <- alternative_f()
Sub Common Components:
Component 1 (“\(r\)”)
This is the formula used to calculate component 1
Show all the details
\[\begin{equation}
r = X \times \lambda_1 + (1 - X) \times \lambda_2
\label{eq:3}
\tag{3}
\end{equation}\]
Where:
- \(r\): one-liner for r
- \(X\): one-liner for X
- \(\lambda_1\): one-liner for \(\lambda_1\)
- \(\lambda_2\): one-liner for \(\lambda_2\)
# - inputs: factors of r
# - outputs: r value
chunk_r <- function(){
###############################################################################
###############################################################################
r_function_f <- function(r_input1_var = r_input1_so , r_input2_var = r_input2_so) {
r_input1_var - r_input2_var
}
###############################################################################
###############################################################################
return(list("r_function_f" = r_function_f))
}
invisible( list2env(chunk_r(),.GlobalEnv) )
Component 2 (“\(q\)”)
This is the formula used to calculate component 2
Show all the details
\[\begin{equation}
q = \text{input} \times \alpha_0 (1 + g)^{X}(1 + \hat{\beta_1} X + \hat{\beta_2} X^2)
\label{eq:}
\tag{4}
\end{equation}\]
Where:
- \(q\): one-liner to define q
- \(\alpha_0\): one-liner to define \(\alpha_0\)
- \(g\): one-liner to define g
- \(\hat{\beta_1}\): one-liner to define \(\hat{\beta_1}\)
- \(\hat{\beta_2}\): one-liner to define \(\hat{\beta_2}\)
# - inputs: factors of q
# - outputs: q value
chunk_q <- function(){
###############################################################################
###############################################################################
q_function_f <- function(q_input1_var = q_input1_so , q_input2_var = q_input2_so) {
(q_input1_var * q_input2_var)^2
}
###############################################################################
###############################################################################
return(list("q_function_f" = q_function_f))
}
invisible( list2env(chunk_q(),.GlobalEnv) )
Component 3 (“\(k\)”)
This is the formula used to calculate component 3
Show all the details
\[\begin{equation}
k = R \times X + (1 - R) \times X
\label{eq:5}
\tag{5}
\end{equation}\]
Where:
- \(k\): one-liner to define k
- \(R\): one-liner to define R
# - inputs: factors of q
# - outputs: q value
chunk_k <- function(){
###############################################################################
###############################################################################
k_function_f <- function(k_input1_var = k_input1_so , k_input2_var = k_input2_so) {
(k_input1_var * k_input2_var)^2
}
###############################################################################
###############################################################################
return(list("k_function_f" = k_function_f))
}
invisible( list2env(chunk_k(),.GlobalEnv) )
Summary of All Approaches
| 1.1 |
Specification of Approach 1 with Part 1 Assumption 1 |
Specification of Approach 1 with Part 2 Assumption 1 |
| 1.2 |
Specification of Approach 1 with Part 1 Assumption 2 |
Specification of Aprroach 1 with Part 2 Assumption 2 |
| 2.1 |
Specification of Approach 2 with Part 1 Assumption 1 |
Specification of Approach 2 with Part 2 Assumption 1 |
| 2.2 |
Specification of Approach 2 with Part 1 Assumption 2 |
Specification of Approach 2 with Part 2 Assumption 2 |
Bolded row is the assumptions and the approach we use to generate the main policy estimate plot.
Main results
Show all the details
#unit test function
unit_test_f <- function(to_test_var, original_var, main_run_var = TRUE){
if (main_run_var == TRUE) {
if (length(to_test_var) > 1) {
fails_test <- ( abs(sd(to_test_var) - original_var) > 0.0001 )
text_val <- sd(to_test_var)
} else {
fails_test <- ( abs(to_test_var - original_var) > 0.0001 )
text_val <- to_test_var
}
if (fails_test) {
print(paste("Output has change at",
deparse(substitute(to_test_var) ),
" to ", text_val) )
}
}
}
one_run <-
function(r_input1_var1 = r_input1_so,
r_input2_var1 = r_input2_so,
q_input1_var1 = q_input1_so,
q_input2_var1 = q_input2_so,
k_input1_var1 = k_input1_so,
k_input2_var1 = k_input2_so){# Variables needed to generate the final policy estimates
r_in <- r_function_f(r_input1_var = r_input1_var1,
r_input2_var = r_input2_var1)
q_in <- q_function_f(q_input1_var = q_input1_var1,
q_input2_var = q_input2_var1)
k_in <- k_function_f(k_input1_var = k_input1_var1,
k_input2_var = k_input2_var1)
return (list("r_in" = r_in,
"q_in" = q_in,
"k_in" = k_in))
}
invisible(list2env(one_run(), .GlobalEnv))
# - perform the calculations to achieve final results
result1 <- mainequation_f(r_final_var = r_in,
q_final_var = q_in,
k_final_var = k_in)
result2 <- alternative_f(r_final_var = r_in,
q_final_var = q_in,
k_final_var = k_in)
#...
results_table <- data.frame("results1" = c("results", NA,
NA) ,
"results2" = c(NA, "results", NA),
"results3" = c("results", NA,
"results"),
row.names = c("situation1", "situation2", "situation3"))
kable(results_table, caption = "Table Caption") %>%
kable_styling("striped", full_width = F)
Table 3.1: Table Caption
|
|
results1
|
results2
|
results3
|
|
situation1
|
results
|
NA
|
results
|
|
situation2
|
NA
|
results
|
NA
|
|
situation3
|
NA
|
NA
|
results
|
Monte Carlo Simulations
sim_data1_f <- function(nsims = 1e2,
r_input1_var2,
r_input1_var2_sd,
r_input2_var2,
r_input2_var2_sd,
q_input1_var2,
q_input1_var2_sd,
q_input2_var2,
q_input2_var2_sd,
k_input1_var2,
k_input1_var2_sd,
k_input2_var2,
k_input2_var2_sd){
################
###### Draws
################
start_time <- Sys.time()
set.seed(142857)
r1_sim <- rnorm(n = nsims, mean = r_input1_var2, sd= r_input1_var2_sd)
r2_sim <- rnorm(n = nsims, mean = r_input2_var2, sd= r_input2_var2_sd)
q1_sim <- rnorm(n = nsims, mean = q_input1_var2, sd= q_input1_var2_sd)
q2_sim <- rnorm(n = nsims, mean = q_input2_var2, sd= q_input2_var2_sd)
k1_sim <- rnorm(n = nsims, mean = k_input1_var2, sd= k_input1_var2_sd)
k2_sim <- rnorm(n = nsims, mean = k_input2_var2, sd= k_input2_var2_sd)
################
###### Runs
################
result1_sim <- rep(NA, nsims) #result1
result2_sim <- rep(NA, nsims) #result2
for (i in 1:nsims){
invisible(list2env(
one_run(r_input1_var1 = r1_sim[i],
r_input2_var1 = r2_sim[i],
q_input1_var1 = q1_sim[i],
q_input2_var1 = q2_sim[i],
k_input1_var1 = k1_sim[i],
k_input2_var1 = k2_sim[i]
), .GlobalEnv))
result1_sim[i] <- mainequation_f(r_final_var = r_in,
q_final_var = q_in,
k_final_var = k_in)
result2_sim[i] <- alternative_f(r_final_var = r_in,
q_final_var = q_in,
k_final_var = k_in)
}
total_time <- Sys.time() - start_time
return(list("result1_sim" = result1_sim,
"result2_sim" = result2_sim))
}
policy_estimates_varnames <- c(
"result1_sim",
"result2_sim"
)
policy_estimates_text <- c(
"Main Equation",
"Alternative Equation"
)
# Run Monte Carlo simulation for our main model
result1_sim_all <- sim_data1_f(nsims = nsims_so,
r_input1_var2 = r_input1_so,
r_input1_var2_sd = r_input1_so * 0.1,
r_input2_var2 = r_input2_so,
r_input2_var2_sd = r_input2_so * 0.1,
q_input1_var2 = q_input1_so,
q_input1_var2_sd = q_input1_so * 0.1,
q_input2_var2 = q_input2_so,
q_input2_var2_sd = q_input2_so * 0.1,
k_input1_var2 = k_input1_so,
k_input1_var2_sd = k_input1_so * 0.1,
k_input2_var2 = k_input2_so,
k_input2_var2_sd = k_input2_so * 0.1
)
################
###### Results/Viz
################
library(plotly)
plot1 <- generate_plot_f(result1_sim_all, policy_estimate_so, rescale_so)[[1]] +
labs(y = NULL,
x = "Main Estimate" ,
title = "Project Title",
subtitle = "Distribution of Key Indicator"
)
print(plot1)

References
LS0tCnRpdGxlOiAiPGNlbnRlcj48ZGl2IGNsYXNzPSAnbXl0aXRsZSc+VGVtcGxhdGU8L2Rpdj48L2NlbnRlcj4iCmRhdGU6ICI8Y2VudGVyPjxkaXYgY2xhc3M9J215c3VidGl0bGUnPmByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgPC9kaXY+PC9jZW50ZXI+IgphdXRob3I6ICI8Y2VudGVyPjxkaXYgY2xhc3MgPSAnY29udHJpYnV0b3JzJz5Db250cmlidXRvcnM8L2Rpdj48L2NlbnRlcj4iCm91dHB1dDoKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgY3NzOiBzdHlsZS5jc3MKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGluY2x1ZGVzOgogICAgICBhZnRlcl9ib2R5OiBmb290ZXIuaHRtbAogICAga2VlcF9tZDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgc21vb3RoX3Njcm9sbDogbm8KICAgIHRoZW1lOiBjZXJ1bGVhbgogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZWQ6IG5vCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDogeWVzCiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzMnCiAgd29yZF9kb2N1bWVudDogbnVsbApsaW5rLWNpdGF0aW9uczogeWVzCnBkZl9kb2N1bWVudDoKICBleHRyYV9kZXBlbmRlbmNpZXM6IHhjb2xvcgogIGZpZ19jYXB0aW9uOiBubwpiaWJsaW9ncmFwaHk6IGJpYmxpb2dyYXBoeS5iaWIKCmtuaXQ6CiAgIyByZW5kZXIgdG8gaW5kZXguaHRtbCBmb3IgR2l0SHViIHBhZ2VzCiAgIyByZW5kZXIgdG8gMDVfZmluYWxfb3BhLmh0bWwgdG8ga25pdCBsb2NhbGx5CiAgIyBZQU1MIGRvZXMgbm90IHN1cHBvcnQgY29tbWVudGluZyBpbnNpZGUgdGhlIGZ1bmN0aW9uCiAgKGZ1bmN0aW9uKGlucHV0X2ZpbGUsIGVuY29kaW5nKSB7CiAgcm1hcmtkb3duOjpyZW5kZXIoaW5wdXRfZmlsZSwgZW5jb2Rpbmc9ZW5jb2RpbmcsIG91dHB1dF9maWxlPWZpbGUucGF0aCgiLi4iLCAnaW5kZXguaHRtbCcpKTsKICBybWFya2Rvd246OnJlbmRlcihpbnB1dF9maWxlLCBlbmNvZGluZz1lbmNvZGluZywgb3V0cHV0X2ZpbGU9JzAwX3RlbXBsYXRlLmh0bWwnKTsKICB9KQotLS0KXGRlZlxibHVle1xjb2xvcntibHVlfX0KXGRlZlxyZWR7XGNvbG9ye3JlZH19CgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0UsIHB1cmwgPSBGQUxTRX0KIyBMb2FkaW5nIHJlcXVpcmVkIGxpYnJhcmllcwpsaXN0Lm9mLnBhY2thZ2VzIDwtIGMoInRpZHl2ZXJzZSIsICJoZXJlIiwgImthYmxlRXh0cmEiLCAicmVhZHhsIiwicGxvdGx5IiwKICAgICAgICAgICAgICAgICAgICAgICAgImJvb2tkb3duIiwgInJvb3RTb2x2ZSIsInNoaW55QlMiLCAic2hpbnl0aGVtZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAiZ2dwbG90MiIpCgpuZXcucGFja2FnZXMgPC0gbGlzdC5vZi5wYWNrYWdlc1shKGxpc3Qub2YucGFja2FnZXMgJWluJSBpbnN0YWxsZWQucGFja2FnZXMoKVssIlBhY2thZ2UiXSldCmlmKGxlbmd0aChuZXcucGFja2FnZXMpKSBpbnN0YWxsLnBhY2thZ2VzKG5ldy5wYWNrYWdlcywgcmVwb3M9ICJodHRwOi8vY3Jhbi5jbnIuYmVya2VsZXkuZWR1LyIpCgpsYXBwbHkobGlzdC5vZi5wYWNrYWdlcywgbGlicmFyeSwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQoKa25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBoZXJlKCkpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCnNldHdkKGhlcmUoKSkKCiMgUHVybCB0byBhbGxfYW5hbHlzaXMuUgpvcHRpb25zKGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpICMgd29ya2Fyb3VuZCBmb3IgcHVybCBlcnJvcgprbml0cjo6cHVybCgiY29kZS8wMF90ZW1wbGF0ZS5SbWQiLCAiY29kZS9zaGlueV9hcHAvYWxsX2FuYWx5c2lzLlIiKQoKcHJpbnRfY29kZSA8LSBUUlVFCmBgYAoKCmBgYHtyIHBhcmFtZXRlcnMsIGVjaG89cHJpbnRfY29kZX0KIyBEbyBub3QgcnVuIGRhdGEgc2V0IG9uIGdpdC9naXRodWIgdW50aWwgcHJpdmFjeSBoYXMgYmVlbiBjbGVhcmVkCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMgRGF0YSAgCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIwojIyMjIyBSZXNlYXJjaAojIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMgR3Vlc3Mgd29yayAgIAojIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMgIE5vdGVzOgojIyMjIyMjIyMjIyMjIyMjCiMjIyBTb3VyY2UgLS0tLT4gIElucHV0IC0tLS0+IE1vZGVsIC0tLS0+IFBvbGljeSBFc3RpbWF0ZXMgKG91dHB1dCkKIyMjICAoX3NvKSAgICAgICAgKF9pbikgICAgICAgKF9tbykgICAgICAgIChfcGUpCiMjIyB2YWx1ZXMgICAgICBmdW5jdGlvbnMgICBmdW5jdGlvbnMgICAgICB2YWx1ZXMKIyMjICAgICAgICAgICAgICYgdmFsdWVzICAgICYgdmFsdWVzCiMjIyBhcmd1bWVudHMgaW4gZnVuY3Rpb25zIHNob3VsZCB1c2VkICJfdmFyIiBhbmQgZnVuY3Rpb25zIHNob3VsZCAiX2YiCiNpbnZpc2libGUoIGxpc3QyZW52KGNhbGxfcGFyYW1zX2YoKSwuR2xvYmFsRW52KSApCgoKIyBFYWNoIGFuYWx5dGljIGNvZGUgY2h1bmsgd2lsbCBiZWdpbiBieSBsaXN0aW5nIGFsbCB0aGUgaW5wdXRzIGl0IG5lZWRzLCBhbmQKIyB0aGUgb3V0cHV0cyBpdCBwcm9kdWNlcy4KIyAtIGlucHV0czogbGlzdAojIC0gb3V0cHV0czogbGlzdAojIyMjIFRoZSBrZXkgZXNzZW50aWFsIGFuYWx5dGljIHN0ZXBzIGFyZSB3cmFwdGVkIGluIGEgZnVuY3Rpb24gICAKI2NodW5rX25hbWVfb2ZfY2h1bmsgPC0gZnVuY3Rpb24oKXsKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiMKIyBoZXJlIGdvZXMgdGhlIGVzc2VudGlhbCBhbmFseXRpYyBjb250ZW50CiMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiMgICAgcmV0dXJuKCApICAgICAgICAgICAgICAgICAgICAgICAgICMgQSBsaXN0IHdpdGggYWxsIHRoZSBvYmplY3RzCiN9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgZ2VuZXJhdGVkIGluc2lkZSB0aGUgZnVuY3Rpb24KIyBUaGUgZm9sbG93aW5nIGxpbmUgZXhlY3V0ZXMgdGhlIGNvZGUgY2h1bmsgYW5kIGRlcG9zaXRzIGl0cyByZXN1bHRzCiMgaW50byB0aGUgY3VycmVudCBSIGVudmlvcm5tZW50OgojaW52aXNpYmxlKCBsaXN0MmVudihjaHVua19uYW1lX29mX2NodW5rKCksLkdsb2JhbEVudikgKQojCiMjIyMjIEV4ZWN1dGUgdmFsdWVzIG9mIHRoZSBmdW5jdGlvbnMgYWJvdmUgd2hlbiBuZWVkZWQgZm9yIHRoZSB0ZXh0OgojIEFueXRoaW5nIHVuZGVyIHRoaXMgY29tbWVudCBpcyB0byBjcmVhdGUgb2JqZWN0cyB0aGF0IGFyZSB1c2VkIGluIHRoZSBib2R5IG9mCiMgdGV4dC4gTm90IHRvIGJlIHVzZWQgaW4gdGhlIGZpbmFsIHJlc3VsdHMgKGNvdWxkIGJlIGRlbGV0ZWQpLiBFYWNoIG9mIHRoZXNlCiMgb2JqZWN0IHNob3VsZCBlbmQgd2l0aCB0aGUgc3VmZml4IF90ZW1wCgpgYGAKCgpgYGB7ciBzb3VyY2VzLCBldmFsID0gVFJVRSwgZWNobz1wcmludF9jb2RlLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIC0gaW5wdXRzOiBub25lCiMgLSBvdXRwdXRzOiBhbGwgc291cmNlcyBjb21pbmcgZnJvbSBkYXRhLCByZXNlYXJjaCBhbmQgZ3Vlc3N3b3JrCmNodW5rX3NvdXJjZXMgPC0gZnVuY3Rpb24oKXsKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgogICAgIyMjIyMjIyMjIyMjIwogICAgIyMjIyMgU2V0dXAKICAgICMjIyMjIyMjIyMjIyMgIAogICAgbnNpbXNfc28gPC0gMWU0CiAgICBwb2xpY3lfZXN0aW1hdGVfc28gPC0gIk1haW4gRXF1YXRpb24iCiAgICByZXNjYWxlX3NvIDwtIFRSVUUKICAgICMjIyMjIyMjIyMjIyMKICAgICMjIyMjIERhdGEgIAogICAgIyMjIyMjIyMjIyMjIwoKICAjIENyZWF0ZSBvYmplY3RzIGZvciBkYXRhIGV4dHJhY3RlZCBmcm9tIHZhcmlvdXMgc291cmNlcwoKICAgIHJfaW5wdXQxX3NvIDwtIDAuMQogICAgcl9pbnB1dDJfc28gPC0gMC4yCiAgICAjIyMjIyMjIyMjIyMjCiAgICAjIyMjIyBSZXNlYXJjaAogICAgIyMjIyMjIyMjIyMjIwoKICAjIENyZWF0ZSBvYmplY3RzIGZvciBwYXJhbWV0ZXJzIGV4dHJhY3RlZCBmcm9tIHJlc2VhcmNoIHBhcGVycwogICAgcV9pbnB1dDFfc28gPC0gMC41CiAgICBxX2lucHV0Ml9zbyA8LSAwLjgKICAgICMjIyMjIyMjIyMjIyMKICAgICMjIyMjIEd1ZXNzIHdvcmsgICAKICAgICMjIyMjIyMjIyMjIyMKCiAgIyBDcmVhdGUgb2JqZWN0cyBmb3IgdmFyaWFibGVzIGZyb20gZWR1Y2F0ZWQgZ3Vlc3NlcyBvciBlc3RpbWF0ZXMgIAoKCiAgICAjIyMjIyMjIyMjIyMjCiAgICAjIyMjIyBOb3RlczoKICAgICMjIyMjIyMjIyMjIyMKCiAgIyBOb3RlcyBmb3IgdGhlIG9iamVjdHMgZGVmaW5lZCBhYm92ZSwgaW5jbHVkaW5nIHNvdXJjZXMsIGV4cGxhbmF0aW9ucywgZXRjLgogICAga19pbnB1dDFfc28gPC0gMwogICAga19pbnB1dDJfc28gPC0gNAoKICAgICNyZXR1cm4oIHNhcHBseSggbHMocGF0dGVybj0gIl9zb1xcYiIpLCBmdW5jdGlvbih4KSBnZXQoeCkpICkKICAgIHJldHVybiAoCiAgICAgIGxpc3QoIm5zaW1zX3NvIiA9IG5zaW1zX3NvLAogICAgICAgICAgICJwb2xpY3lfZXN0aW1hdGVfc28iID0gcG9saWN5X2VzdGltYXRlX3NvLAogICAgICAgICAgICJyZXNjYWxlX3NvIiA9IHJlc2NhbGVfc28sCiAgICAgICAgICAgInJfaW5wdXQxX3NvIiA9IHJfaW5wdXQxX3NvLAogICAgICAgICAgICJyX2lucHV0Ml9zbyIgPSByX2lucHV0Ml9zbywKICAgICAgICAgICAicV9pbnB1dDFfc28iID0gcV9pbnB1dDFfc28sCiAgICAgICAgICAgInFfaW5wdXQyX3NvIiA9IHFfaW5wdXQyX3NvLAogICAgICAgICAgICJrX2lucHV0MV9zbyIgPSBrX2lucHV0MV9zbywKICAgICAgICAgICAia19pbnB1dDJfc28iID0ga19pbnB1dDJfc28KICAgICAgICAgICApCiAgICApCn0KaW52aXNpYmxlKGxpc3QyZW52KGNodW5rX3NvdXJjZXMoKSwuR2xvYmFsRW52KSApCmBgYAoKIyBJbnRyb2R1Y3Rpb24KU3VtbWFyeSBvZiB0aGUgaXNzdWUgYW5kIGludHJvZHVjdGlvbiB0byB0aGUgcG9saWN5IGFuYWx5c2lzIGlzIGNvbmR1Y3RlZC4KClRoZSBnb2FsIG9mIHRoaXMgYW5hbHlzaXMgaXMgdG8gcHJvdmlkZSB0aGUgYmVzdCBlbXBpcmljYWwgaW5mb3JtYXRpb24gZm9yIHBvbGljeSBtYWtlcnMgZGViYXRpbmcgdGhlIGltcGxlbWVudGF0aW9uIG9mICJtYXNzIGRld29ybWluZyBpbnRlcnZlbnRpb25zIiBwb2xpY3kuIFRoaXMgZG9jdW1lbnQgZGVzY3JpYmVzIGFsbCB0aGUgYW5hbHl0aWNhbCBzdGVwcyByZXF1aXJlZCB0byByZXByb2R1Y2UgdGhlIGFuYWx5c2lzLCBhbmQgZGlzcGxheWluZyB0aGUgYWN0dWFsIGNvbXB1dGVyIGNvZGUgdXNlIGluIGVhY2ggc3RlcC4gSW4gYWRkaXRpb24gdG8gdGhpcyByZXBvcnQsIHRoZSByZWFkZXIgY2FuIGZpbmQgYWxsIHRoZSBtYXRlcmlhbHMgdG8gcmVwcm9kdWNlIHRoZSBmaW5kaW5ncyBwcmVzZW50ZWQgaGVyZSBpbiBHaXRIdWIuIFRoZSBtYWluIG91dHB1dCwgcHJlc2VudGVkIGluIHRoZSByZXN1bHRzIHNlY3Rpb24gb2YgdGhpcyByZXBvcnQsIGNhbiBhbHNvIGJlIGV4cGxvcmVkIGludGVyYWN0aXZlbHkgZm9yIGRpZmZlcmVudCBhc3N1bXB0aW9ucyBvbiB0aGUgY29ycmVzcG9uZGluZyBzaGlueSBhcHAuCgojIyBTb3VyY2UgSW5mb3JtYXRpb24gZm9yIGRhdGEgKyBhbmFseXRpY2FsIG1ldGhvZHMKCkZvciB0aGlzIGR5bmFtaWMgZG9jdW1lbnQsIHdlIGFyZSBjb25kdWN0aW5nIHRoaXMgc3BlY2lmaWMgYW5hbHlzaXMsIGFuZCBpdCBpcyBjb21wdXRlZCB1c2luZyB0aHJlZSBkaWZmZXJlbnQgYXBwcm9hY2hlczoKCjEuIFtBcHByb2FjaCAxXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWJhaXJkMjAxNndvcm1zKQoKSW4gdGhpcyBmaXJzdCBhcHByb2FjaCwgdGhlIGVmZmVjdCBvbiBlYXJuaW5ncyBvdmVyIHRoZSBlbnRpcmUgbGlmZWN5Y2xlIGlzIHByZWRpY3RlZCBieSBleHRyYXBvbGF0aW5nIHRoZSBlZmZlY3RzIG9uIGhvdXJzIHdvcmtlZCBieSBpbmRpdmlkdWFscyBpbiB0aGUgb3JpZ2luYWwgdHJlYXRtZW50IGdyb3VwLCB0ZW4geWVhcnMgYWZ0ZXIgdGhlIGludGVydmVudGlvbi4KCjIuIFtBcHByb2FjaCAyXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWtscHM0KQoKSW4gdGhpcyBzZWNvbmQgYXBwcm9hY2gsIGJlbmVmaXRzIGZvbGxvdyB0aGUgc2FtZSBwcmluY2lwbGUgYXMgaW4gYXBwcm9hY2ggMSAoaW5jcmVhc2UgaW4gbGlmZXRpbWUgZWFybmluZ3MpLCBidXQgaXQgdXNlcyB1cGRhdGVkIGRhdGEgb24gdGhlIGVmZmVjdHMgb24gdGhlIGxhYm9yIG1hcmtldCBvdXRjb21lcy4gSW5zdGVhZCBvZiBwcm9qZWN0aW5nIGEgdHJlbmQgb2YgZWFybmluZ3MgaW50byB0aGUgZnV0dXJlIChhZnRlciB0aGUgZXN0aW1hdGVkIGltcGFjdCBvZiB0aGUgMTAgeWVhciBmb2xsb3ctdXApLCB0aGlzIGFuYWx5c2lzIHVzZXMgYWRkaXRpb25hbCBkYXRhIGZyb20gMTUgYW5kIDIwIHllYXIgZm9sbG93LXVwcyBhZnRlciB0aGUgb3JpZ2luYWwgaW50ZXJ2ZW50aW9uLgoKMy4gW0FwcHJvYWNoIDNdKGh0dHBzOi8vYml0c3Mtb3BhLmdpdGh1Yi5pby9vcGEtZGV3b3JtaW5nLyMyM19BcHByb2FjaF8zOl9Db21iaW5hdGlvbl9vZl9QcmV2aW91c19BcHByb2FjaGVzX2FuZF9JbnB1dF9Gcm9tX0tleV9Qb2xpY3lfUGFydG5lcnMpCgpJbiB0aGlzIHRoaXJkIGFuZCBmaW5hbCBhcHByb2FjaCwgdGhlIHJlcG9ydCBib3Jyb3dlZCBzb21lIG1ldGhvZG9sb2dpY2FsIGVsZW1lbnRzIGZyb20gQmFpcmQgZXQgYWwuIChbMjAxNl0oaHR0cHM6Ly9iaXRzcy1vcGEuZ2l0aHViLmlvL29wYS1kZXdvcm1pbmcvI3JlZi1iYWlyZDIwMTZ3b3JtcykpIGFuZCBIYW1vcnkgZXQgYWwuIChbMjAyMF0oaHR0cHM6Ly9iaXRzcy1vcGEuZ2l0aHViLmlvL29wYS1kZXdvcm1pbmcvI3JlZi1rbHBzNCkpIGFuZCBzb3VnaHQgZmVlZGJhY2sgZnJvbSBhIGtleSBwb2xpY3kgcGFydG5lciB0byBiZXN0IGlkZW50aWZ5IG9uZSBjbGVhciBvdXRwdXQgdG8gaW5mb3JtIHBvbGljeSBtYWtlcnMuIEJJVFNTIHdvcmtlZCBpbiBjb2xsYWJvcmF0aW9uIHdpdGggdGhlIE5HTyBFdmlkZW5jZSBBY3Rpb24sIGEga2V5IHRlY2huaWNhbCBhc3Npc3RhbmNlIHBhcnRuZXIgaW4gdGhpcyBhcmVhLiBFdmlkZW5jZSBBY3Rpb24gcHJvdmlkZWQgaW5zaWdodHMgb24gd2hhdCBhcmUgdGhlIG1vc3QgcmVsZXZhbnQgY29zdHMgYW5kIGJlbmVmaXRzIGZyb20gdGhlIHBlcnNwZWN0aXZlcyBvZiBwb2xpY3kgbWFrZXJzLCBhbmQgb24gY2VydGFpbiBhc3BlY3RzIG9mIHRoZSBhbmFseXNpcyB0aGF0IGNvdWxkIGJlIHVwZGF0ZWQgd2l0aCBwcmVzZW50LWRheSBkYXRhLgoKCgo/Pz8gIAoKIyMgS2V5IHBvbGljeSBlc3RpbWF0ZXMgZm9yIHBvbGljeSBtYWtlcnMgIApgYGB7cn0KI215IHRob3VnaHRzOiBzaG91bGQgd2UgZm9yZWZyb250IHRoZSBjb25jbHVzaW9ucyBiZWZvcmUgdGhlIG1ldGhvZG9sb2d5PwoKI1NhbmRyYTogSSB0aGluayB3ZSBzaG91bGQgc3BlY2lmeSB3aGljaCBhcHByb2FjaCB3ZSB1c2UgdG8gZ2VuZXJhdGUgdGhlIGdyYXBoLCBidXQga2VlcCB0aGUgbWV0aG9kb2xvZ3kgYmVmb3JlIHRoZSBjb25jbHVzaW9ucy4KYGBgCgpgYGB7ciBmaW5hbC1vdXRwdXR9CmBgYAo/Pz8KCiMgTWV0aG9kb2xvZ3kKCkV4cGxhaW4gd2hhdCB0aGUgZmluYWwgZXN0aW1hdGUgaW5kaWNhdG9yIGlzLCBob3cgdGhlIGFuYWx5c2lzIGlzIHRvIGJlIHBlcmZvcm1lZCwgd2hhdCBmYWN0b3JzIGFyZSBsb29rZWQgYXQsIGV0Yy4KClRoZSBmaW5hbCBlc3RpbWF0ZSBpcyB0aGUgbmV0IHByZXNlbnQgdmFsdWUgb2YgdGhlIGRld29ybWluZyB0cmVhdG1lbnQsIHJlZmVycmVkIHRvIGFzIHRoZSBOZXQgUHJlc2VudCBWYWx1ZSAoTlBWKS4gVGhlIHJlcG9ydCBmaXJzdCBkZXNjcmliZXMgdGhlIGNvbW1vbiBlbGVtZW50cyBhY3Jvc3MgYWxsIHRocmVlIGFwcHJvYWNoZXMsIGFuZCB0aGVuIGRlc2NyaWJlIGVhY2ggYXBwcm9hY2ggaW4gZGV0YWlsLgoKIyMgQ29tbW9uIFN0cnVjdHVyZQoKSW50cm9kdWNlIHRoZSBzdGFydGluZyBwb2ludCBhbmQgdGhlIGZpbmFsIHBvbGljeSBlc3RpbWF0ZS4gSW5jbHVkZSBhbHRlcm5hdGl2ZSBpbmRpY2F0b3JzIG9mIG91ciBmaW5hbCBwb2xpY3kgZXN0aW1hdGVzIGFzIHdlbGwuICAKClRoZSBzdGFydGluZyBwb2ludCBpcyBhIGNvbXBhcmlzb24gb2YgYSBzdHJlYW0gb2YgYmVuZWZpdHMgYW5kIGNvc3RzIG92ZXIgdGhlIGxpZmV0aW1lIG9mIHRoZSByZWNpcGllbnRzIG9mIGRld29ybWluZy4gVGhlIGZpbmFsIHBvbGljeSBlc3RpbWF0ZSBpcyB0aGUgZGlzY291bnRlZCBzdW0gb2YgYWxsIGNvc3RzIGFuZCBiZW5lZml0cywga25vd24gYXMgdGhlIE5ldCBQcmVzZW50IFZhbHVlIChOUFYpLiBCZW5lZml0cyBhcmUgZXF1YWwgdG8gdGhlIGFkZGl0aW9uYWwgbGlmZXRpbWUgZWFybmluZ3MgdGhhdCBpbmRpdmlkdWFscyBhcmUgZXhwZWN0ZWQgdG8gZ2VuZXJhdGUgZHVlIHRvIGRld29ybWluZyB0cmVhdG1lbnQuIFRoZXNlIGFkZGl0aW9uYWwgZWFybmluZ3MgYXJlIGNvbXB1dGVkIGFzIGEgZGlzY291bnRlZCBzdW0gb3ZlciB0aGVpciB3b3JraW5nIGxpZmV0aW1lLgoKQXQgYSBoaWdoIGxldmVsIGFsbCB0aHJlZSBhcHByb2FjaGVzIGZvY3VzIG9uIHRoZSBzYW1lIHR5cGUgb2YgYmVuZWZpdHM6IHRoZSBpbmNyZWFzZSBpbiBpbmNvbWVzIG92ZXIgdGhlIGxpZmV0aW1lIG9mIGJlbmVmaWNpYXJpZXMgb2YgZGV3b3JtaW5nLiBUaGlzIGlzIGxpa2VseSBhbiB1bmRlci1lc3RpbWF0ZSBvZiB0aGUgYmVuZWZpdHMgYXMgaXQgZG9lcyBub3QgcXVhbnRpZnkgdGhlIG5vbi1wZWN1bmlhcnkgZWZmZWN0cyBvZiBpbXByb3ZlZCBoZWFsdGguIFRoZSBjb3N0cyBjYW4gYmUgc2VwYXJhdGVkIGludG8gZGlyZWN0IGNvc3RzIG9mIGltcGxlbWVudGluZyBhbmQgZXZhbHVhdGluZyBkZXdvcm1pbmcgcHJvZ3JhbXMsIGFuZCBpbmRpcmVjdCBjb3N0cywgc3VjaCBhcyBhZGRpdGlvbmFsIGNvc3RzIHRvIHRoZSBlZHVjYXRpb24gc3lzdGVtIGFzIGEgcmVzdWx0IG9mIGluY3JlYXNlZCBjaGlsZCBhdHRlbmRhbmNlLCBhc3NvY2lhdGVkIHdpdGggdGhlIGJlbmVmaXRzIG9mIGRld29ybWluZy4KClRoZSBtYWluIGRpZmZlcmVuY2VzIGluIGJlbmVmaXRzIGFjcm9zcyB0aGUgdGhyZWUgYXBwcm9hY2hlcyBoYXZlIHRvIGRvIHdpdGggaG93IHRvIHByZWRpY3QgdGhlIGVhcm5pbmdzIHByb2ZpbGVzIG92ZXIgYSBsaWZlY3ljbGUsIGFuZCBob3cgdG8gYWNjb3VudCBmb3IgZGlmZmVyZW5jZXMgaW4gd29ybSBwcmV2YWxlbmNlIHJhdGVzIGFuZCBsZW5ndGggb2YgdHJlYXRtZW50IGFjcm9zcyBzZXR0aW5ncy4gQXBwcm9hY2hlcyAxIGFuZCAyIHVzZSBkaWZmZXJlbnQgZWFybmluZyBwcm9maWxlcywgYW5kIGFwcHJvYWNoIDMgY29tYmluZXMgYm90aCBlYXJuaW5nIHByb2ZpbGVzIGFuZCBhZGp1c3RzIGZvciBwb3NzaWJsZSBkaWZmZXJlbmNlcyBpbiBwcmV2YWxlbmNlIHJhdGVzIG9mIHdvcm0gaW5mZWN0aW9ucyBhbmQgbGVuZ3RoIG9mIHRyZWF0bWVudC4KClRoZSBtYWluIGRpZmZlcmVuY2VzIGluIGNvc3RzIGJldHdlZW4gc2NlbmFyaW9zIGhhdmUgdG8gZG8gd2l0aCBhKSB3aGV0aGVyIGluZGlyZWN0IGNvc3RzIGFyZSBpbmNsdWRlZCwgYW5kIGIpIGhvdyB0byBjb21wdXRlIHRoZSByZWxldmFudCB1bml0IGNvc3QgZm9yIHRoZSBhbmFseXNpcy4gVGhlIGZpcnN0IHR3byBhcHByb2FjaGVzIGluY2x1ZGUgaW5kaXJlY3QgY29zdHMgYW5kIHVzZSB0aGUgdW5pdCBjb3N0cyBvZiBhIHNwZWNpZmljIGNvdW50cnkgKEtlbnlhKSB3aGVyZSB0aGUgc3R1ZHkgd2FzIG9yaWdpbmFsbHkgY29uZHVjdGVkLCB3aGlsZSB0aGUgdGhpcmQgYXBwcm9hY2ggZG9lcyBub3QgaW5jbHVkZSBpbmRpcmVjdCBjb3N0cyBhbmQgdXNlIHVuaXQgY29zdHMgb2YgdmFyaW91cyBjb3VudHJpZXMgZnJvbSBkYXRhIHByb3ZpZGVkIGJ5IEV2aWRlbmNlIEFjdGlvbi4KCiMjIyBNYWluIEVxdWF0aW9uICh0aGUgbW9kZWwpCgpFeHBsYW5hdGlvbiBmb3IgdGhlIG1haW4gZXF1YXRpb24KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CnkgPSByICsgcSAtIGsKXGxhYmVse2VxOjF9Clx0YWd7MX0KXGVuZHtlcXVhdGlvbn0KCldoZXJlOgoKLSAkeSQ6IG9uZS1saW5lciB0byBkZWZpbmUgeQotICRyJDogb25lLWxpbmVyIHRvIGRlZmluZSByCi0gJGskOiBvbmUtbGluZXIgdG8gZGVmaW5lIGsKCjwvZGV0YWlscz4KCgoKIyMjIEFsdGVybmF0aXZlIEVxdWF0aW9uCgpFeHBsYW5hdGlvbiBmb3IgdGhlIGFsdGVybmF0aXZlIGVxdWF0aW9uCgo8ZGV0YWlscz48c3VtbWFyeT5TaG93IGFsbCB0aGUgZGV0YWlsczwvc3VtbWFyeT4KXGJlZ2lue2VxdWF0aW9ufQp5ID0gciArIHEgKyBrClxsYWJlbHtlcToyfQpcdGFnezJ9ClxlbmR7ZXF1YXRpb259CgpXaGVyZToKCi0gJHkkOiBvbmUtbGluZXIgdG8gZGVmaW5lIHkKLSAkciQ6IG9uZS1saW5lciB0byBkZWZpbmUgcgotICRrJDogb25lLWxpbmVyIHRvIGRlZmluZSBrCgpgYGB7ciB0ZXN0LCBldmFsPVRSVUV9CiMgLSBpbnB1dHM6CiMgLSBvdXRwdXRzOgpjaHVua190ZXN0IDwtIGZ1bmN0aW9uKCl7CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCgogICAgIyByYW5kb20gZXF1YXRpb24gdG8gdXNlIGFzIG91ciBtYWluIGVxdWF0aW9uIHRvIGdldCB0aGUgZmluYWwgcmVzdWx0CiAgICBtYWluZXF1YXRpb25fZiA8LSBmdW5jdGlvbihyX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrX2ZpbmFsX3ZhciA9IDEpIHsKICAgICAgICByZXR1cm4gKHJfZmluYWxfdmFyICsgcV9maW5hbF92YXIgLSBrX2ZpbmFsX3ZhcikKICAgIH0KCiAgICAjIHJhbmRvbSBlcXVhdGlvbiB0byB1c2UgYXMgb3VyIGFsdGVybmF0aXZlIGVxdWF0aW9uIHRvIGdldCB0aGUgZmluYWwgcmVzdWx0CiAgICBhbHRlcm5hdGl2ZV9mIDwtIGZ1bmN0aW9uKCByX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrX2ZpbmFsX3ZhciA9IDEpewogICAgICByZXR1cm4gKHJfZmluYWxfdmFyICsgcV9maW5hbF92YXIgKyBrX2ZpbmFsX3ZhcikKCiAgICB9CgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgIAogICAgcmV0dXJuKGxpc3QoIm1haW5lcXVhdGlvbl9mIiA9IG1haW5lcXVhdGlvbl9mLCAiYWx0ZXJuYXRpdmVfZiIgPSBhbHRlcm5hdGl2ZV9mKSkgICAgIyBUcnkgdG8gcmV0dXJuIG9ubHkgZnVuY3Rpb25zCn0KaW52aXNpYmxlKCBsaXN0MmVudihjaHVua190ZXN0KCksLkdsb2JhbEVudikgKQoKIyMjIyMgRXhlY3V0ZSB2YWx1ZXMgb2YgdGhlIGZ1bmN0aW9ucyBhYm92ZSB3aGVuIG5lZWRlZCBmb3IgdGhlIHRleHQ6Cm1haW5lcXVhdGlvbl9pbiA8LSBtYWluZXF1YXRpb25fZigpCmFsdGVybmF0aXZlX2luIDwtIGFsdGVybmF0aXZlX2YoKQpgYGAKCgo8L2RldGFpbHM+CgojIyBTdWIgQ29tbW9uIENvbXBvbmVudHM6CgojIyMgQ29tcG9uZW50IDEgKCIkciQiKQoKVGhpcyBpcyB0aGUgZm9ybXVsYSB1c2VkIHRvIGNhbGN1bGF0ZSBjb21wb25lbnQgMVteMV0KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CnIgPSBYIFx0aW1lcyBcbGFtYmRhXzEgICsgKDEgLSBYKSBcdGltZXMgXGxhbWJkYV8yClxsYWJlbHtlcTozfQpcdGFnezN9ClxlbmR7ZXF1YXRpb259CgpXaGVyZToKCi0gJHIkOiBvbmUtbGluZXIgZm9yIHIKLSAkWCQ6IG9uZS1saW5lciBmb3IgWAotICRcbGFtYmRhXzEkOiBvbmUtbGluZXIgZm9yICRcbGFtYmRhXzEkCi0gJFxsYW1iZGFfMiQ6IG9uZS1saW5lciBmb3IgJFxsYW1iZGFfMiQKCmBgYHtyIGNvbXAxLCAgZWNobz1wcmludF9jb2RlLCBldmFsPVRSVUV9CiMgLSBpbnB1dHM6IGZhY3RvcnMgb2YgcgojIC0gb3V0cHV0czogciB2YWx1ZQpjaHVua19yIDwtIGZ1bmN0aW9uKCl7CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCgogICAgcl9mdW5jdGlvbl9mIDwtIGZ1bmN0aW9uKHJfaW5wdXQxX3ZhciA9IHJfaW5wdXQxX3NvICwgcl9pbnB1dDJfdmFyID0gcl9pbnB1dDJfc28pIHsgIAogICAgICAgIHJfaW5wdXQxX3ZhciAtIHJfaW5wdXQyX3ZhcgoKICAgIH0KCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiAgICByZXR1cm4obGlzdCgicl9mdW5jdGlvbl9mIiA9IHJfZnVuY3Rpb25fZikpCn0KCmludmlzaWJsZSggbGlzdDJlbnYoY2h1bmtfcigpLC5HbG9iYWxFbnYpICkKCmBgYAo8L2RldGFpbHM+CgojIyBBcHByb2FjaCAxOiBbQmFpcmQgZXQgYWwuXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWJhaXJkMjAxNndvcm1zKQojIyMgQ29tcG9uZW50IDIgKCIkcSQiKQoKVGhpcyBpcyB0aGUgZm9ybXVsYSB1c2VkIHRvIGNhbGN1bGF0ZSBjb21wb25lbnQgMlteMl0KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CnEgPSAgXHRleHR7aW5wdXR9IFx0aW1lcyBcYWxwaGFfMCAoMSArIGcpXntYfSgxICsgXGhhdHtcYmV0YV8xfSBYICsgXGhhdHtcYmV0YV8yfSBYXjIpClxsYWJlbHtlcTp9Clx0YWd7NH0KXGVuZHtlcXVhdGlvbn0KCldoZXJlOgoKLSAkcSQ6IG9uZS1saW5lciB0byBkZWZpbmUgcQotICRcYWxwaGFfMCQ6IG9uZS1saW5lciB0byBkZWZpbmUgJFxhbHBoYV8wJAotICRnJDogb25lLWxpbmVyIHRvIGRlZmluZSBnCi0gJFxoYXR7XGJldGFfMX0kOiBvbmUtbGluZXIgdG8gZGVmaW5lICRcaGF0e1xiZXRhXzF9JAotICRcaGF0e1xiZXRhXzJ9JDogb25lLWxpbmVyIHRvIGRlZmluZSAkXGhhdHtcYmV0YV8yfSQKCgpgYGB7ciBjb21wMiwgIGVjaG89cHJpbnRfY29kZSwgZXZhbD1UUlVFfQojIC0gaW5wdXRzOiBmYWN0b3JzIG9mIHEKIyAtIG91dHB1dHM6IHEgdmFsdWUKY2h1bmtfcSA8LSBmdW5jdGlvbigpewojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgIAoKICAgIHFfZnVuY3Rpb25fZiA8LSBmdW5jdGlvbihxX2lucHV0MV92YXIgPSBxX2lucHV0MV9zbyAsIHFfaW5wdXQyX3ZhciA9IHFfaW5wdXQyX3NvKSB7ICAKICAgICAgICAocV9pbnB1dDFfdmFyICogcV9pbnB1dDJfdmFyKV4yCgogICAgfQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICAKICAgIHJldHVybihsaXN0KCJxX2Z1bmN0aW9uX2YiID0gcV9mdW5jdGlvbl9mKSkKfQoKaW52aXNpYmxlKCBsaXN0MmVudihjaHVua19xKCksLkdsb2JhbEVudikgKQoKYGBgCjwvZGV0YWlscz4KCiMjIEFwcHJvYWNoIDI6IFtIYW1vcnkgZXQgYWwuXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWtscHM0KQojIyMgQ29tcG9uZW50IDMgKCIkayQiKQoKVGhpcyBpcyB0aGUgZm9ybXVsYSB1c2VkIHRvIGNhbGN1bGF0ZSBjb21wb25lbnQgM1teM10KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CmsgPSBSIFx0aW1lcyBYICArICgxIC0gUikgXHRpbWVzIFgKXGxhYmVse2VxOjV9Clx0YWd7NX0KXGVuZHtlcXVhdGlvbn0KCldoZXJlOgoKLSAkayQ6IG9uZS1saW5lciB0byBkZWZpbmUgawotICRSJDogb25lLWxpbmVyIHRvIGRlZmluZSBSCgoKYGBge3IgY29tcDMsICBlY2hvPXByaW50X2NvZGUsIGV2YWw9VFJVRX0KIyAtIGlucHV0czogZmFjdG9ycyBvZiBxCiMgLSBvdXRwdXRzOiBxIHZhbHVlCmNodW5rX2sgPC0gZnVuY3Rpb24oKXsKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICAKCiAgICBrX2Z1bmN0aW9uX2YgPC0gZnVuY3Rpb24oa19pbnB1dDFfdmFyID0ga19pbnB1dDFfc28gLCBrX2lucHV0Ml92YXIgPSBrX2lucHV0Ml9zbykgeyAgCiAgICAgICAgKGtfaW5wdXQxX3ZhciAqIGtfaW5wdXQyX3ZhcileMgoKICAgIH0KCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiAgICByZXR1cm4obGlzdCgia19mdW5jdGlvbl9mIiA9IGtfZnVuY3Rpb25fZikpCn0KCmludmlzaWJsZSggbGlzdDJlbnYoY2h1bmtfaygpLC5HbG9iYWxFbnYpICkKCgpgYGAKCjwvZGV0YWlscz4KIyMgU3VtbWFyeSBvZiBBbGwgQXBwcm9hY2hlcwoKCnwgQXBwcm9hY2ggICAgfCBQYXJ0IDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUGFydCAyICAgICAgICB8CnwtLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLXwKfCAxLjEgfCBTcGVjaWZpY2F0aW9uIG9mIEFwcHJvYWNoIDEgd2l0aCBQYXJ0IDEgQXNzdW1wdGlvbiAxIHwgU3BlY2lmaWNhdGlvbiBvZiBBcHByb2FjaCAxIHdpdGggUGFydCAyIEFzc3VtcHRpb24gMSAgfAp8IDEuMiB8IFNwZWNpZmljYXRpb24gb2YgQXBwcm9hY2ggMSB3aXRoIFBhcnQgMSBBc3N1bXB0aW9uIDIgfCBTcGVjaWZpY2F0aW9uIG9mIEFwcnJvYWNoIDEgd2l0aCBQYXJ0IDIgQXNzdW1wdGlvbiAyICB8CnwgMi4xIHwgU3BlY2lmaWNhdGlvbiBvZiBBcHByb2FjaCAyIHdpdGggUGFydCAxIEFzc3VtcHRpb24gMSB8IFNwZWNpZmljYXRpb24gb2YgQXBwcm9hY2ggMiB3aXRoIFBhcnQgMiBBc3N1bXB0aW9uIDEgfAp8ICoqMi4yKiogfCAqKlNwZWNpZmljYXRpb24gb2YgQXBwcm9hY2ggMiB3aXRoIFBhcnQgMSBBc3N1bXB0aW9uIDIqKiB8ICoqU3BlY2lmaWNhdGlvbiBvZiBBcHByb2FjaCAyIHdpdGggUGFydCAyIEFzc3VtcHRpb24gMioqfAoKQm9sZGVkIHJvdyBpcyB0aGUgYXNzdW1wdGlvbnMgYW5kIHRoZSBhcHByb2FjaCB3ZSB1c2UgdG8gZ2VuZXJhdGUgdGhlIG1haW4gcG9saWN5IGVzdGltYXRlIHBsb3QuCgoKIyBNYWluIHJlc3VsdHMKPGRldGFpbHM+PHN1bW1hcnk+U2hvdyBhbGwgdGhlIGRldGFpbHM8L3N1bW1hcnk+CmBgYHtyIGFsbC1zdGVwcywgIGVjaG89cHJpbnRfY29kZSwgZXZhbCA9IFRSVUV9CiN1bml0IHRlc3QgZnVuY3Rpb24KdW5pdF90ZXN0X2YgPC0gZnVuY3Rpb24odG9fdGVzdF92YXIsIG9yaWdpbmFsX3ZhciwgbWFpbl9ydW5fdmFyID0gVFJVRSl7CiAgICBpZiAobWFpbl9ydW5fdmFyID09IFRSVUUpIHsKICAgICAgICBpZiAobGVuZ3RoKHRvX3Rlc3RfdmFyKSA+IDEpIHsKICAgICAgICAgICAgZmFpbHNfdGVzdCA8LSAoIGFicyhzZCh0b190ZXN0X3ZhcikgLSBvcmlnaW5hbF92YXIpID4gMC4wMDAxICkKICAgICAgICAgICAgdGV4dF92YWwgPC0gc2QodG9fdGVzdF92YXIpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmFpbHNfdGVzdCA8LSAoIGFicyh0b190ZXN0X3ZhciAtIG9yaWdpbmFsX3ZhcikgPiAwLjAwMDEgKQogICAgICAgICAgICB0ZXh0X3ZhbCA8LSB0b190ZXN0X3ZhcgogICAgICAgIH0KICAgICAgICBpZiAoZmFpbHNfdGVzdCkgewogICAgICAgICAgICBwcmludChwYXN0ZSgiT3V0cHV0IGhhcyBjaGFuZ2UgYXQiLAogICAgICAgICAgICAgICAgICAgICAgICBkZXBhcnNlKHN1YnN0aXR1dGUodG9fdGVzdF92YXIpICksCiAgICAgICAgICAgICAgICAgICAgICAgICIgdG8gIiwgdGV4dF92YWwpICkKICAgICAgICB9CiAgICAgIH0KfQoKb25lX3J1biA8LQogIGZ1bmN0aW9uKHJfaW5wdXQxX3ZhcjEgPSByX2lucHV0MV9zbywKICAgICAgICAgICByX2lucHV0Ml92YXIxID0gcl9pbnB1dDJfc28sCiAgICAgICAgICAgcV9pbnB1dDFfdmFyMSA9IHFfaW5wdXQxX3NvLAogICAgICAgICAgIHFfaW5wdXQyX3ZhcjEgPSBxX2lucHV0Ml9zbywKICAgICAgICAgICBrX2lucHV0MV92YXIxID0ga19pbnB1dDFfc28sCiAgICAgICAgICAga19pbnB1dDJfdmFyMSA9IGtfaW5wdXQyX3NvKXsjIFZhcmlhYmxlcyBuZWVkZWQgdG8gZ2VuZXJhdGUgdGhlIGZpbmFsIHBvbGljeSBlc3RpbWF0ZXMKCiAgICByX2luIDwtIHJfZnVuY3Rpb25fZihyX2lucHV0MV92YXIgPSByX2lucHV0MV92YXIxLAogICAgICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyID0gcl9pbnB1dDJfdmFyMSkKICAgIHFfaW4gPC0gcV9mdW5jdGlvbl9mKHFfaW5wdXQxX3ZhciA9IHFfaW5wdXQxX3ZhcjEsCiAgICAgICAgICAgICAgICAgICAgICAgICBxX2lucHV0Ml92YXIgPSBxX2lucHV0Ml92YXIxKQogICAga19pbiA8LSBrX2Z1bmN0aW9uX2Yoa19pbnB1dDFfdmFyID0ga19pbnB1dDFfdmFyMSwKICAgICAgICAgICAgICAgICAgICAgICAgIGtfaW5wdXQyX3ZhciA9IGtfaW5wdXQyX3ZhcjEpCiAgICByZXR1cm4gKGxpc3QoInJfaW4iID0gcl9pbiwKICAgICAgICAgICAgICAgICAicV9pbiIgPSBxX2luLAogICAgICAgICAgICAgICAgICJrX2luIiA9IGtfaW4pKQogICAgICAgICAgIH0KCmludmlzaWJsZShsaXN0MmVudihvbmVfcnVuKCksIC5HbG9iYWxFbnYpKQoKCmBgYAoKPC9kZXRhaWxzPgpgYGB7ciBtYWluLXJlc3VsdHMsICBlY2hvPXByaW50X2NvZGUsIGV2YWwgPSBUUlVFfQojIC0gcGVyZm9ybSB0aGUgY2FsY3VsYXRpb25zIHRvIGFjaGlldmUgZmluYWwgcmVzdWx0cwoKcmVzdWx0MSA8LSBtYWluZXF1YXRpb25fZihyX2ZpbmFsX3ZhciA9IHJfaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcV9maW5hbF92YXIgPSBxX2luLAogICAgICAgICAgICAgICAgICAgICAgICAgIGtfZmluYWxfdmFyID0ga19pbikKcmVzdWx0MiA8LSBhbHRlcm5hdGl2ZV9mKHJfZmluYWxfdmFyID0gcl9pbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IHFfaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAga19maW5hbF92YXIgPSBrX2luKQojLi4uCgpyZXN1bHRzX3RhYmxlIDwtIGRhdGEuZnJhbWUoInJlc3VsdHMxIiA9ICAgYygicmVzdWx0cyIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQSkgLAogICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0czIiID0gIGMoTkEsICJyZXN1bHRzIiwgTkEpLAogICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0czMiID0gYygicmVzdWx0cyIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0cyIpLAoKICAgICAgICAgICAgICAgICAgICAgICAgcm93Lm5hbWVzID0gYygic2l0dWF0aW9uMSIsICJzaXR1YXRpb24yIiwgInNpdHVhdGlvbjMiKSkKCmthYmxlKHJlc3VsdHNfdGFibGUsIGNhcHRpb24gPSAiVGFibGUgQ2FwdGlvbiIpICU+JQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikKYGBgCgoKYGBge3IgZ2VuZXJhdGUtcGxvdC1mdW5jdGlvbiwgcHVybCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0KIyBnZW5lcmF0ZV9wbG90X2Y6IGZ1bmN0aW9uIHRvIGdlbmVyYXRlIHBsb3RzIGZvciBib3RoIER5bmFtaWMgRG9jdW1lbnQgYW5kCiMgc2hpbnkgYXBwLiBJdCB0YWtlcyBpbiB0aGUgc2ltdWxhdGVkIGRhdGEsIHBvbGljeSBlc3RpbWF0ZSB0ZXh0LCBhbmQgcmVzY2FsZQojIHZhcmlhYmxlLiBUaGVzZSBhcmUgaW50ZXJtZWRpYXJ5IHZhcmlhYmxlcyB0byBleGNsdWRlIHRoZSBpbnRlcmFjdGl2aXR5IG9mCiMgc2hpbnkgYXBwIGZyb20gdGhlIHBsb3QgZ2VuZXJhdGlvbiBwcm9jZXNzLiAgCmNodW5rX2dlbmVyYXRlX3Bsb3QgPC0gZnVuY3Rpb24oKSB7CiAgZ2VuZXJhdGVfcGxvdF9mIDwtIGZ1bmN0aW9uKHJlc3VsdDFfc2ltX2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9saWN5X2VzdGltYXRlc190ZXh0X3NlbGVjdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNjYWxlLCBTRCA9IEZBTFNFKXsKICAgIHRvdGFsX3RpbWVfc2ltIDwtIHJlc3VsdDFfc2ltX2FsbCR0b3RhbF90aW1lX3NpbQogICAgcG9zaXRpb24gPC0gd2hpY2goIHBvbGljeV9lc3RpbWF0ZXNfdGV4dCA9PSBwb2xpY3lfZXN0aW1hdGVzX3RleHRfc2VsZWN0ZWQpCiAgICByZXN1bHQxX3NpbSA8LSByZXN1bHQxX3NpbV9hbGxbWyBwb2xpY3lfZXN0aW1hdGVzX3Zhcm5hbWVzW3Bvc2l0aW9uXSBdXSAgICAKICAgIHJlc3VsdDFfZm9yX3RleHQgPC0gcGFzdGUoIk1lZGlhbiBOUFY6ICIsIHJvdW5kKG1lZGlhbihyZXN1bHQxX3NpbSksIDIpKQogICAgcmVzdWx0MV9mb3JfdGV4dDIgPC0gTlVMTAogICAgaWYgKFNEKXsKICAgIHJlc3VsdDFfZm9yX3RleHQyIDwtIHBhc3RlKCJTRCBOUFY6ICIsIHJvdW5kKHNkKHJlc3VsdDFfc2ltKSwgMikpCiAgICB9CiAgICBwbG90MSA8LSBnZ3Bsb3QoKSArCiAgICAgIGdlb21fZGVuc2l0eSgKICAgICAgICBhZXMoeCA9IHJlc3VsdDFfc2ltLAogICAgICAgICAgICBhbHBoYSA9IDEgLyAyLCAuLnNjYWxlZC4uKSwKICAgICAgICBrZXJuZWwgPSAiZ2F1IiwKICAgICAgICBsd2QgPSAxLAogICAgICAgIGZpbGwgPSAiIzAwN2JhNyIsCiAgICAgICAgY29sb3IgPSAiZGFya2JsdWUiLAogICAgICAgIGFscGhhID0gMC4zCiAgICAgICkgKwogICAgICBnZW9tX3ZsaW5lKAogICAgICAgIHhpbnRlcmNlcHQgPSBjKDAsIG1lZGlhbihyZXN1bHQxX3NpbSkpLAogICAgICAgIGNvbCA9IGMoImJsYWNrIiwgImRhcmtibHVlIiksCiAgICAgICAgbHdkID0gYygxLCAxKSwKICAgICAgICBsaW5ldHlwZSA9IGMoInNvbGlkIiwgImRhc2hlZCIpCiAgICAgICkgKwogICAgICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTMwMCwxMDAwKSwgIHlsaW0gPSAgYyggMCwgMS4yICkpICArICAjIGZpeGluZyB0aGUgeCBheGlzIHNvIHNoaWZ0cyBpbiB0aGUgZGVuc2l0eSBjYW4gYmUgc2VlbgogICAgICAjeGxpbShyYW5nZShkZW5zaXR5KHJlc3VsdDFfc2ltKSR4KSkgKwogICAgICBndWlkZXMoYWxwaGEgPSAibm9uZSIsIGNvbG91ciA9ICJub25lIikgKwogICAgICBzY2FsZV94X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAsIDApKSkgKwogICAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAsIDApKSkgKwogICAgICBhbm5vdGF0ZSgKICAgICAgICAidGV4dCIsCiAgICAgICAgeCA9IDEgKiBtZWRpYW4ocmVzdWx0MV9zaW0pLAogICAgICAgIHkgPSAwLjIsCiAgICAgICAgbGFiZWwgPSByZXN1bHQxX2Zvcl90ZXh0LAogICAgICAgIHNpemUgPSA2LAogICAgICAgIGNvbG9yID0gImRhcmtibHVlIgogICAgICApICsKICAgICAgYW5ub3RhdGUoCiAgICAgICAgInRleHQiLAogICAgICAgIHggPSAxICogbWVkaWFuKHJlc3VsdDFfc2ltKSwKICAgICAgICB5ID0gMC4xLAogICAgICAgIGxhYmVsID0gcmVzdWx0MV9mb3JfdGV4dDIsCiAgICAgICAgc2l6ZSA9IDYsCiAgICAgICAgY29sb3IgPSAiZGFya2JsdWUiCiAgICAgICkgKwogICAgICB0aGVtZSgKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEuNSkKICAgICAgKQoKICAgIGlmIChyZXNjYWxlID09IFRSVUUpIHsKICAgICAgcGxvdDEgPC0KICAgICAgICBzdXBwcmVzc01lc3NhZ2VzKHBsb3QxICsgY29vcmRfY2FydGVzaWFuKHhsaW0gPSAxLjIgKiBjKG1pbihjKAogICAgICAgICAgLTEsIHJlc3VsdDFfc2ltCiAgICAgICAgKSksIG1heChjKAogICAgICAgICAgMTAwLCByZXN1bHQxX3NpbQogICAgICAgICkpKSkpCiAgICB9CiAgICByZXR1cm4gKGxpc3QocGxvdDEscG9zaXRpb24sdG90YWxfdGltZV9zaW0pKQp9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCnJldHVybihsaXN0KCJnZW5lcmF0ZV9wbG90X2YiID0gZ2VuZXJhdGVfcGxvdF9mKSkKfQoKaW52aXNpYmxlKCBsaXN0MmVudihjaHVua19nZW5lcmF0ZV9wbG90KCksLkdsb2JhbEVudikgKQpgYGAKCiMgTW9udGUgQ2FybG8gU2ltdWxhdGlvbnMgIApgYGB7ciBtYy1zZXR1cCwgIGVjaG89cHJpbnRfY29kZSwgZXZhbCA9IFRSVUV9CgpzaW1fZGF0YTFfZiA8LSBmdW5jdGlvbihuc2ltcyA9IDFlMiwKICAgICAgICAgICAgICAgICAgICAgIHJfaW5wdXQxX3ZhcjIsCiAgICAgICAgICAgICAgICAgICAgICByX2lucHV0MV92YXIyX3NkLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMiwKICAgICAgICAgICAgICAgICAgICAgIHJfaW5wdXQyX3ZhcjJfc2QsCiAgICAgICAgICAgICAgICAgICAgICBxX2lucHV0MV92YXIyLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDFfdmFyMl9zZCwKICAgICAgICAgICAgICAgICAgICAgIHFfaW5wdXQyX3ZhcjIsCiAgICAgICAgICAgICAgICAgICAgICBxX2lucHV0Ml92YXIyX3NkLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDFfdmFyMiwKICAgICAgICAgICAgICAgICAgICAgIGtfaW5wdXQxX3ZhcjJfc2QsCiAgICAgICAgICAgICAgICAgICAgICBrX2lucHV0Ml92YXIyLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDJfdmFyMl9zZCl7CiAgICAjIyMjIyMjIyMjIyMjIyMjCiAgICAjIyMjIyMgRHJhd3MgICAKICAgICMjIyMjIyMjIyMjIyMjIyMgIAogIHN0YXJ0X3RpbWUgPC0gU3lzLnRpbWUoKQogIHNldC5zZWVkKDE0Mjg1NykKICByMV9zaW0gPC0gcm5vcm0obiA9IG5zaW1zLCBtZWFuID0gcl9pbnB1dDFfdmFyMiwgc2Q9IHJfaW5wdXQxX3ZhcjJfc2QpCiAgcjJfc2ltIDwtIHJub3JtKG4gPSBuc2ltcywgbWVhbiA9IHJfaW5wdXQyX3ZhcjIsIHNkPSByX2lucHV0Ml92YXIyX3NkKQogIHExX3NpbSA8LSBybm9ybShuID0gbnNpbXMsIG1lYW4gPSBxX2lucHV0MV92YXIyLCBzZD0gcV9pbnB1dDFfdmFyMl9zZCkKICBxMl9zaW0gPC0gcm5vcm0obiA9IG5zaW1zLCBtZWFuID0gcV9pbnB1dDJfdmFyMiwgc2Q9IHFfaW5wdXQyX3ZhcjJfc2QpCiAgazFfc2ltIDwtIHJub3JtKG4gPSBuc2ltcywgbWVhbiA9IGtfaW5wdXQxX3ZhcjIsIHNkPSBrX2lucHV0MV92YXIyX3NkKQogIGsyX3NpbSA8LSBybm9ybShuID0gbnNpbXMsIG1lYW4gPSBrX2lucHV0Ml92YXIyLCBzZD0ga19pbnB1dDJfdmFyMl9zZCkKCgoKCgogICAgIyMjIyMjIyMjIyMjIyMjIwogICAgIyMjIyMjIFJ1bnMgICAgCiAgICAjIyMjIyMjIyMjIyMjIyMjCgogIHJlc3VsdDFfc2ltIDwtIHJlcChOQSwgbnNpbXMpICNyZXN1bHQxCiAgcmVzdWx0Ml9zaW0gPC0gcmVwKE5BLCBuc2ltcykgI3Jlc3VsdDIKCiAgZm9yIChpIGluIDE6bnNpbXMpewogICAgaW52aXNpYmxlKGxpc3QyZW52KAogICAgICBvbmVfcnVuKHJfaW5wdXQxX3ZhcjEgPSByMV9zaW1baV0sCiAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMSA9IHIyX3NpbVtpXSwKICAgICAgICAgICAgICBxX2lucHV0MV92YXIxID0gcTFfc2ltW2ldLAogICAgICAgICAgICAgIHFfaW5wdXQyX3ZhcjEgPSBxMl9zaW1baV0sCiAgICAgICAgICAgICAga19pbnB1dDFfdmFyMSA9IGsxX3NpbVtpXSwKICAgICAgICAgICAgICBrX2lucHV0Ml92YXIxID0gazJfc2ltW2ldCiAgICAgICAgICAgICAgKSwgLkdsb2JhbEVudikpCgogICAgcmVzdWx0MV9zaW1baV0gPC0gbWFpbmVxdWF0aW9uX2Yocl9maW5hbF92YXIgPSByX2luLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFfZmluYWxfdmFyID0gcV9pbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBrX2ZpbmFsX3ZhciA9IGtfaW4pCiAgICByZXN1bHQyX3NpbVtpXSA8LSBhbHRlcm5hdGl2ZV9mKHJfZmluYWxfdmFyID0gcl9pbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IHFfaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAga19maW5hbF92YXIgPSBrX2luKQogIH0KICAgIHRvdGFsX3RpbWUgPC0gU3lzLnRpbWUoKSAtIHN0YXJ0X3RpbWUKICAgIHJldHVybihsaXN0KCJyZXN1bHQxX3NpbSIgPSByZXN1bHQxX3NpbSwKICAgICAgICAgICAgICAgICJyZXN1bHQyX3NpbSIgPSByZXN1bHQyX3NpbSkpCgoKfQoKcG9saWN5X2VzdGltYXRlc192YXJuYW1lcyA8LSBjKAogICJyZXN1bHQxX3NpbSIsCiAgInJlc3VsdDJfc2ltIgopCgpwb2xpY3lfZXN0aW1hdGVzX3RleHQgPC0gYygKICAiTWFpbiBFcXVhdGlvbiIsCiAgIkFsdGVybmF0aXZlIEVxdWF0aW9uIgopCgpgYGAKCmBgYHtyIG1jLXJ1biwgZHBpID0gNDAwLCBlY2hvID0gcHJpbnRfY29kZSwgZXZhbCA9IFRSVUV9CiMgUnVuIE1vbnRlIENhcmxvIHNpbXVsYXRpb24gZm9yIG91ciBtYWluIG1vZGVsCnJlc3VsdDFfc2ltX2FsbCA8LSBzaW1fZGF0YTFfZihuc2ltcyA9IG5zaW1zX3NvLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDFfdmFyMiA9IHJfaW5wdXQxX3NvLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDFfdmFyMl9zZCA9IHJfaW5wdXQxX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMiA9IHJfaW5wdXQyX3NvLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMl9zZCA9IHJfaW5wdXQyX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDFfdmFyMiA9IHFfaW5wdXQxX3NvLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDFfdmFyMl9zZCA9IHFfaW5wdXQxX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDJfdmFyMiA9IHFfaW5wdXQyX3NvLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDJfdmFyMl9zZCA9IHFfaW5wdXQyX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDFfdmFyMiA9IGtfaW5wdXQxX3NvLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDFfdmFyMl9zZCA9IGtfaW5wdXQxX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDJfdmFyMiA9IGtfaW5wdXQyX3NvLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDJfdmFyMl9zZCA9IGtfaW5wdXQyX3NvICogMC4xCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKCgoKIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMgUmVzdWx0cy9WaXoKIyMjIyMjIyMjIyMjIyMjIwoKCmxpYnJhcnkocGxvdGx5KQoKCnBsb3QxIDwtIGdlbmVyYXRlX3Bsb3RfZihyZXN1bHQxX3NpbV9hbGwsIHBvbGljeV9lc3RpbWF0ZV9zbywgcmVzY2FsZV9zbylbWzFdXSArCiAgICAgIGxhYnMoeSA9IE5VTEwsCiAgICAgICB4ID0gIk1haW4gRXN0aW1hdGUiICwKICAgICAgIHRpdGxlID0gIlByb2plY3QgVGl0bGUiLAogICAgICAgc3VidGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIEtleSBJbmRpY2F0b3IiCiAgICAgICApCnByaW50KHBsb3QxKQpgYGAKCgoKCiMgUmVmZXJlbmNlcwoKClteMV06IE5vdGVzIG9mIHJlZmVyZW5jZWQgc2VjdGlvbgoKClteMl06IE5vdGVzIG9uIHJlZmVyZW5jZWQgc2VjdGlvbgoKW14zXTogTm90ZXMgb24gcmVmZXJlbmNlZCBzZWN0aW9uCg==

An Open Policy Analysis by BITSS
See a full contributors list here
openpolicy@berkeley.edu